package cn.kone.blog.service.impl;


import cn.kone.blog.domain.Article;
import cn.kone.blog.domain.query.ArticleQuery;
import cn.kone.blog.dto.ArticleDTO;
import cn.kone.blog.dto.ArticleGDDTO;
import cn.kone.blog.mapper.ArticleMapper;
import cn.kone.blog.service.IArticleService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public class ArticleServiceImpl implements IArticleService {
    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    //查询单个
    @Override
    public Article findOne(Long id) {
        return articleMapper.findOne(id);
    }

    //查询全部
    @Override
    public List<Article> findAll() {

        return articleMapper.findAll();

    }

    //新增
    @Override
    @Transactional
    public void addArticle(Article article) {
        article.setArticleCommentNum(0);
        article.setArticleReadCount(0);
        article.setArticleStarNum(0);
        articleMapper.addArticle(article);
        //新增到MongoDB中
        mongoTemplate.insert(article);
    }

    //修改
    @Override
    @Transactional
    public void updateArticle(Article article) {
        article.setUpdateTime(new Date());
        articleMapper.updateArticle(article);
        //先查询MongoDB中是否有
        Query query = new Query(Criteria.where("id").is(article.getId()));
        Article one = mongoTemplate.findOne(query, Article.class);
        if (one != null){
            article.set_id(one.get_id());
            mongoTemplate.save(article);
        }

    }


    //删除
    @Override
    @Transactional
    public void deleteArticle(Long id) {
        articleMapper.deleteArticle(id);
        //先查询MongoDB中是否有
        Query query = new Query(Criteria.where("id").in(id));
        Article one = mongoTemplate.findOne(query, Article.class);
        if (one != null){
            mongoTemplate.remove(one);
        }
    }

    //分页+高级查询
    @Override
    public List<Article> pageQuery(ArticleQuery articleQuery) {
        PageHelper.startPage(articleQuery.getCurrentPage(), articleQuery.getPageSize());
        return articleMapper.pageQuery(articleQuery);
    }

    //批量删除
    @Override
    @Transactional
    public void batchDeleteArticle(Long[] ids) {
        articleMapper.batchDeleteArticle(ids);
        Query query = new Query(Criteria.where("id").in(ids));
        mongoTemplate.findAllAndRemove(query, Article.class);
    }

    /**
     * 侧边栏文章归档
     * @return
     */
    @Override
    public List<ArticleDTO> articleTimeStatistics() {
        return articleMapper.articleTimeStatistics();
    }

    /**
     * 相关文章查询
     * @param id
     * @return
     */
    @Override
    public List<Article> relateArticle(Long id) {
        Article one = articleMapper.findOne(id);

        return articleMapper.relateArticle(one);
    }

    /**
     * 头部栏文章归档
     * @return
     */
    @Override
    public List<ArticleGDDTO> articleGD() {
        //查询出对应年份的文章集合
        List<Article> articleList = articleMapper.articleGD();
        //将文章类型的集合转换为map collect的key就是年份 collect的value就是当前年份的文章名称和月份和日期
        Map<String, List<Article>> collect = articleList.stream().collect(Collectors.groupingBy(Article::getYear));
        //创建一个list的集合将collect的数据封装到这个list集合中
        List<ArticleGDDTO> articleGDDTOS = new ArrayList<>();

        //遍历collect这个map然后将对应的key和value存放在articleGDDTOS这个集合中
        for (Map.Entry<String,List<Article>> gdmap : collect.entrySet()) {
            ArticleGDDTO gddto = new ArticleGDDTO();
            gddto.setYear(gdmap.getKey());
            gddto.setArticleList(gdmap.getValue());
            articleGDDTOS.add(gddto);
        }


        return articleGDDTOS;
    }

}
